Multi-touch card
The multi-touch card provides multiple touch targets on a list item.
Examples
Default
Variations
Usage
When to use Multi-touch card
- The component should be used when a list item includes a lot of data and requires 2-3 touch targets.
How this component works
- Component should use established color patterns.
Instances of this component in production
- Prescriptions
Accessibility considerations
- The card's type and place in the list (ex. prescription 1 of 1) should be called out first by the screen reader. The screen reader should call out each individual touch target by its respective type (button, link; etc) along with its respective a11y hint.
- Keyboards and Voice Access/Voice Control should navigate through each line item separately
- Keyboards and Voice Access/Voice Control should navigate each touch area separately
- Touch target UI should have clear and distinguishable areas/borders
Code usage
- Properties
- Example
- Source Code
- Accessibility
Name | Type | Default Value | Required | Description |
---|---|---|---|---|
orderIdentifier | string | No | read by screen readers to identify the cards place in a list | |
mainA11yLabel | string | No | accessibility label for the main section | |
mainContent | ReactElement<any, string | JSXElementConstructor<any>> | Yes | content to display in the main section | |
bottomOnPress | () => void | No | called when the bottom button is pressed | |
bottomContent | ReactElement<any, string | JSXElementConstructor<any>> | No | content to display in the bottom button | |
bottomA11yHint | string | No | hint for the bottom button action | |
bottomA11yLabel | string | No | accessibility label for the bottom section |
How to use the MultiTouchCard component
<CrisisLineCta onPress={onCrisisLine} />
Full code for the MultiTouchCard component
import React, { FC, ReactElement } from 'react'
import { Pressable, PressableProps } from 'react-native'
import { HiddenA11yElement } from 'styles/common'
import { useTheme } from 'utils/hooks'
import Box, { BoxProps } from './Box'
export type MultiTouchCardProps = {
/** read by screen readers to identify the cards place in a list */
orderIdentifier?: string
/** accessibility label for the main section */
mainA11yLabel?: string
/** content to display in the main section */
mainContent: ReactElement
/** called when the bottom button is pressed */
bottomOnPress?: () => void
/** content to display in the bottom button */
bottomContent?: ReactElement
/** hint for the bottom button action */
bottomA11yHint?: string
/** accessibility label for the bottom section */
bottomA11yLabel?: string
}
const MultiTouchCard: FC<MultiTouchCardProps> = ({
orderIdentifier,
mainContent,
bottomContent,
bottomOnPress,
bottomA11yHint,
mainA11yLabel,
bottomA11yLabel,
}) => {
const theme = useTheme()
const hasBottomContent = !!bottomContent
const background = 'list'
let mainBoxProps: BoxProps = {
width: '100%',
minHeight: theme.dimensions.touchableMinHeight,
py: theme.dimensions.buttonPadding,
px: theme.dimensions.gutter,
borderWidth: theme.dimensions.borderWidth,
borderColor: 'primary',
borderStyle: 'solid',
backgroundColor: background,
borderRadiusTop: 8,
borderRadiusBottom: hasBottomContent ? 0 : 8,
}
if (mainA11yLabel) {
mainBoxProps = { ...mainBoxProps, accessibilityLabel: mainA11yLabel }
}
let bottomPressableProps: PressableProps = {
onPress: bottomOnPress,
accessible: true,
accessibilityRole: 'link',
accessibilityHint: bottomA11yHint,
}
let bottomBoxProps: BoxProps = {
py: theme.dimensions.buttonPadding,
px: theme.dimensions.gutter,
backgroundColor: background,
borderRadiusBottom: 8,
borderTopWidth: 0,
borderWidth: theme.dimensions.borderWidth,
borderColor: 'primary',
borderStyle: 'solid',
}
const getBottomContent = () => {
if (bottomOnPress) {
if (bottomA11yLabel) {
bottomPressableProps = { ...mainBoxProps, accessibilityLabel: bottomA11yLabel }
}
return (
<Pressable {...bottomPressableProps}>
<Box {...bottomBoxProps}>{bottomContent}</Box>
</Pressable>
)
} else {
if (bottomA11yLabel) {
bottomBoxProps = { ...mainBoxProps, accessibilityLabel: bottomA11yLabel }
}
return <Box {...bottomBoxProps}>{bottomContent}</Box>
}
}
return (
<>
{orderIdentifier && <HiddenA11yElement accessibilityLabel={orderIdentifier}>{orderIdentifier}</HiddenA11yElement>}
<Box {...mainBoxProps}>{mainContent}</Box>
{hasBottomContent && getBottomContent()}
</>
)
}
export default MultiTouchCard